package com.timebank.system.listener;

import com.alibaba.fastjson2.JSON;
import com.rabbitmq.client.Channel;
import com.timebank.common.core.constant.SecurityConstants;
import com.timebank.common.core.constant.TimeCoinTradeStatusConstant;
import com.timebank.common.core.constant.message.MessageTypeConstant;
import com.timebank.common.core.constant.rabbitmq.queue.QueueConstant;
import com.timebank.common.core.exception.ServiceException;
import com.timebank.common.core.web.pojo.AjaxResult;
import com.timebank.system.pojo.entity.ContractMessage;
import com.timebank.timecoin.pojo.entity.TimeCoinTrade;
import com.timebank.timecoin.pojo.entity.User;
import com.timebank.timecoin.service.RemoteContractService;
import com.timebank.timecoin.service.RemoteTimeCoinService;
import com.timebank.websocket.pojo.vo.SendMsgVO;
import com.timebank.websocket.service.RemoteWebSocketService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.rmi.ServerException;
import java.time.LocalDateTime;

/**
 * 智能合约 消息 监听器
 * @author shiliuyinzhen
 */
@Component
@Slf4j
public class ContractMessageListener {

    @Resource
    private RemoteContractService remoteContractService;


    @Resource
    private RemoteTimeCoinService remoteTimeCoinService;

    @Resource
    private RemoteWebSocketService remoteWebSocketService;

    /**
     * 处理 奖品 服务消息
     *
     * @param msg
     * @param message
     * @param channel
     * @throws IOException
     */
    @RabbitListener(queues = QueueConstant.CONTRACT_MESSAGE_QUEUE)
    @RabbitHandler
    public void HandelVolunteerServiceMessage(String msg, Message message, Channel channel) throws IOException {

        //将json格式字符串转换为对象
        ContractMessage contractMessage = JSON.parseObject(msg, ContractMessage.class);
        log.info("接收到智能合约消息：{}", contractMessage);
        Integer typeId = contractMessage.getTypeId();
        //如果是创建用户
        if (typeId.equals(MessageTypeConstant.CONTRACT_USER_ADD)){
            User user = contractMessage.getUser();
            AjaxResult ajaxResult =
                    remoteContractService.createContractUser(user, SecurityConstants.INNER);
            if (ajaxResult.isError()){
                throw new ServiceException("创建fabric超级账本用户失败");
            }
        } else if (typeId.equals(MessageTypeConstant.CONTRACT_USER_UPDATE)) {
            User user = contractMessage.getUser();
            AjaxResult ajaxResult =
                    remoteContractService.updateContractUser(user, SecurityConstants.INNER);
            if (ajaxResult.isError()){
                throw new ServiceException("更新fabric超级账本用户失败");
            }
            //创建时间币交易
            TimeCoinTrade timeCoinTrade = TimeCoinTrade.builder()
                    .payerId(999L)
                    .payerName("system")
                    .getterId(user.getUserId())
                    .getterName(user.getUserName())
                    .timeCoin(contractMessage.getTimeCoin())
                    .tradeTime(LocalDateTime.now())
                    .status(TimeCoinTradeStatusConstant.PAID)
                    .createBy("system")
                    .createTime(LocalDateTime.now())
                    .remark("累计签到获得时间币")
                    .build();
            ajaxResult = remoteTimeCoinService.createTrade(timeCoinTrade,SecurityConstants.INNER);
            if (ajaxResult.isError()){
                throw new ServiceException("创建累计签到获得时间币交易失败");
            }
            //发送时间币到账消息
            SendMsgVO sendMsgVO = SendMsgVO.builder()
                    .senderName("system")
                    .getterId(user.getUserId().toString())
                    .timeCoin(contractMessage.getTimeCoin())
                    .title("累计签到奖励到账")
                    .content("累计签到获得时间币：" + contractMessage.getTimeCoin())
                    .typeId(MessageTypeConstant.SIGN_GET_TIMECOIN)
                    .build();
            ajaxResult = remoteWebSocketService.sendMessage(sendMsgVO, SecurityConstants.INNER);
            if (ajaxResult.isError()){
                throw new ServerException("发送时间币到账消息失败");
            }
        } else {
            throw new ServerException("未知消息类型");
        }

        try {
            // RabbitMQ的ack机制中，第二个参数返回true，表示需要将这条消息投递给其他的消费者重新消费
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 第三个参数true，表示这个消息会重新进入队列
            //channel.basicNack(deliveryTag, false, true);
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        }
    }
}
